#include "CFormation.h"
#include <math.h>

#define PI 3.14159265

CFormation::TFormationPairs CFormation::formationPairs;
std::set<CFormation*> CFormation::formations;

CFormation::CFormation(BWAPI::Position pos, EFormations form)
:formation(form), target(0), reserved(false)
{
	setCenter(pos);
	formations.insert(this);
}

CFormation::~CFormation()
{
	disbandFormation();
	formations.erase(this);
}

void CFormation::reserve()
{
	this->reserved = true;
}

void CFormation::release()
{
	this->reserved = false;
}

void CFormation::mergeFormations(std::set<CFormation*> merge)
{
	for(std::set<CFormation*>::iterator f = merge.begin(); f != merge.end(); ++f)
	{
		if ((*f) != this)
		{
			for(TUnitMap::iterator u = (*f)->units.begin(); u != (*f)->units.end(); ++u)
			{
				formationPairs.insert(std::make_pair(u->first, this));
				this->units.insert(std::make_pair(u->first, this->units.size()));
			}
			(*f)->units.clear();
			(*f)->target = 0;
		}
	}
	recalculateSlots();
	calcSlotSize();
}

void CFormation::disbandFormation()
{
	TFormationPairs::const_iterator iter = formationPairs.begin();
	for (; iter != formationPairs.end(); ++iter)
	{
		if (iter->second == this)
			formationPairs.erase(iter);
	}
	units.clear();
}

CFormation* CFormation::splitFormation()
{
	BWAPI::Position seperation(this->getDiameter()/2, 0);
	this->setCenter(this->getCenter() + seperation);
	CFormation* newGroup = getEmptyFormation(this->getCenter() - seperation, this->formation);
	int count = units.size() >> 1;
	for (int i = 0; i < count; ++i)
	{
		TUnitMap::const_iterator iter = units.begin();
		newGroup->joinFormation(iter->first);
	}
	return newGroup;
}

void CFormation::setFormation(EFormations f)
{
	formation = f;
	recalculateSlots();
}

BWAPI::Position CFormation::getCenter()
{
	static bool testing;
	if (!testing)
	{
		testing = true;
		if (waypoints.size() > 1 && isWellFormed())
			waypoints.pop_front();
		testing = false;
	}
	return waypoints.front();
}

void CFormation::setCenter(BWAPI::Position pos)
{
	waypoints.clear();
	waypoints.push_back(pos);
}

void CFormation::addWayPoint(BWAPI::Position pos)
{
	waypoints.push_back(pos);
}

BWAPI::Unit* CFormation::getTarget()
{
	if (target && target->getHitPoints() == 0)
		target = 0;
	return target;
}

void CFormation::setTarget(BWAPI::Unit* t)
{
	target = t;
}

CFormation::TUnitMap CFormation::getUnits()
{
	return units;
}

int CFormation::getUnitSlot(BWAPI::Unit* unit)
{
	TUnitMap::const_iterator iter = units.find(unit);
	if (iter != units.end())
		return iter->second;
	return 0;
}

void CFormation::joinFormation(BWAPI::Unit* unit)
{
	if (CFormation* old = getFormation(unit))
		old->leaveFormation(unit);
	formationPairs.insert(std::make_pair(unit, this));
	units.insert(std::make_pair(unit, units.size()));
	recalculateSlots();
	calcSlotSize();
}

void CFormation::leaveFormation(BWAPI::Unit* unit)
{
	formationPairs.erase(unit);
	units.erase(unit);
	if (units.size() == 0) {
		target = 0;
	} else {
		recalculateSlots();
		calcSlotSize();
	}
}

void CFormation::recalculateSlots()
{
	std::map<int, BWAPI::Position> slots;
	for (int i = 0; i < units.size(); ++i)
		slots.insert(std::make_pair(i, getPosition(i)));
	CalculateNearestSlots(units, slots);
}

int CFormation::getDiameter()
{
	int diameter = 0;
	for (int i = 0; i < units.size(); ++i)
	{
		BWAPI::Position pos = this->getPosition(i);
		for (int j = i+1; j < units.size(); ++j)
		{
			BWAPI::Position other = this->getPosition(j);
			int dist = pos.getDistance(other);
			if (dist > diameter)
				diameter = dist;
		}
	}
	return diameter;
}

CFormation* CFormation::getFormation(BWAPI::Unit* unit)
{
	TFormationPairs::const_iterator iter = formationPairs.find(unit);
	if (iter != formationPairs.end())
		return iter->second;
	return 0;
}

bool CFormation::isWellFormed()
{
	for (TUnitMap::iterator iter = units.begin(); iter != units.end(); ++iter)
		if (!isInPosition(iter->first))
			return false;
	return true;
}

bool CFormation::isInPosition(BWAPI::Unit* unit)
{
	BWAPI::Position pos = getPosition(unit);
	if (!(unit->getType().isFlyer()))
		if (unit->getTilePosition().isValid())
			if (!BWTA::isConnected(unit->getTilePosition(), BWAPI::TilePosition(pos)))
				return true;
	return (pos == unit->getPosition());
}

void CFormation::calcSlotSize()
{
	int size = 2;

	for (TUnitMap::const_iterator iter = units.begin(); iter != units.end(); ++iter)
	{
		if (iter->first->getType().spaceRequired() < 10 && iter->first->getType().spaceRequired() > size)
			size = iter->first->getType().spaceRequired();
	}
	slotSize = size*10 + 10;
}

BWAPI::Position CFormation::getPosition(BWAPI::Unit* unit)
{
	return getPosition(getUnitSlot(unit));
}

BWAPI::Position CFormation::getPosition(int slot)
{
	if (units.size() <= 1)
		return getCenter();
	switch (formation)
	{
	case ZFVLine:
		return getCenter() + BWAPI::Position(0, slot * slotSize - slotSize/2 * units.size());
	case ZFHLine:
		return getCenter() + BWAPI::Position(slot * slotSize - slotSize/2 * units.size(), 0);
	case ZFForeslash:
		return getCenter() + BWAPI::Position(-slot * slotSize + slotSize/2 * units.size(), slot * slotSize - slotSize/2 * units.size());
	case ZFBackslash:
		return getCenter() + BWAPI::Position(slot * slotSize - slotSize/2 * units.size(), slot * slotSize - slotSize/2 * units.size());
	case ZFDoubleVLine:
		if (slot%2 == 0)
			return getCenter() + BWAPI::Position(0, slot * slotSize - slotSize/2 * units.size());
		return getCenter() + BWAPI::Position(slotSize, slot * slotSize - slotSize/2 * units.size() - slotSize);
	case ZFDoubleVLineDense:
		if (slot%2 == 0)
			return getCenter() + BWAPI::Position(0, slot * slotSize/2 - slotSize/4 * units.size());
		return getCenter() + BWAPI::Position(slotSize, slot * slotSize/2 - slotSize/4 * units.size() - slotSize/2);
	case ZFDoubleHLine:
		if (slot%2 == 0)
			return getCenter() + BWAPI::Position(slot * slotSize - slotSize/2 * units.size(), 0);
		return getCenter() + BWAPI::Position(slot * slotSize - slotSize/2 * units.size() - slotSize, slotSize);
	case ZFDoubleHLineDense:
		if (slot%2 == 0)
			return getCenter() + BWAPI::Position(slot * slotSize/2 - slotSize/4 * units.size(), 0);
		return getCenter() + BWAPI::Position(slot * slotSize/2 - slotSize/4 * units.size() - slotSize/2, slotSize);
	case ZFCircle:
		{
			int circum = slotSize*(units.size()+1);
			int radius = ((radius = circum/2/PI) > slotSize ? radius : slotSize);
			double angle = 360.0*(slot)/units.size();
			double s = sin(angle * PI/180.0);
			double c = cos(angle * PI/180.0);
			return getCenter() + BWAPI::Position( radius*s, radius*c );
		}
	case ZFCross:
		if (( slot )%4 == 0)
			return getCenter() + BWAPI::Position( slotSize*(( slot )/4 + (units.size()%2 ? 0 : 1)), slotSize*(( slot )/4 + (units.size()%2 ? 0 : 1)));
		if ((slot+3)%4 == 0)
			return getCenter() + BWAPI::Position( slotSize*((slot+3)/4), -slotSize*((slot+3)/4));
		if ((slot+2)%4 == 0)
			return getCenter() + BWAPI::Position(-slotSize*((slot+2)/4),  slotSize*((slot+2)/4));
		if ((slot+1)%4 == 0)
			return getCenter() + BWAPI::Position(-slotSize*((slot+1)/4), -slotSize*((slot+1)/4));
	case ZFPlus:
		if (( slot )%4 == 0)
			return getCenter() + BWAPI::Position( +slotSize*(( slot )/4+1),  0);
		if ((slot+1)%4 == 0)
			return getCenter() + BWAPI::Position( -slotSize*((slot+1)/4), 0);
		if ((slot+2)%4 == 0)
			return getCenter() + BWAPI::Position(0,  slotSize*((slot+2)/4));
		if ((slot+3)%4 == 0)
			return getCenter() + BWAPI::Position(0, -slotSize*((slot+3)/4));
	case ZFDiamond:
		{
			int circum = slotSize*(units.size()+1);
			int radius = 2 * ((radius = circum/2/PI) > slotSize ? radius : slotSize);
			double angle = 360.0*(slot)/units.size();
			double s = sin(angle * PI/180.0) / (abs(cos(angle * PI/180.0)) + 1);
			double c = cos(angle * PI/180.0) / (abs(sin(angle * PI/180.0)) + 1);
			return getCenter() + BWAPI::Position( radius*s, radius*c );
		}
	case ZFBox:
		{
			int width = 1 + ceil(((double)units.size())/4);
			BWAPI::Position topLeft = getCenter() + BWAPI::Position(-slotSize/2*(width-1), -slotSize/2*(width-1));
			BWAPI::Position bottomRight = getCenter() + BWAPI::Position(slotSize/2*(width-1), slotSize/2*(width-1));
			int mid = (width-1)*2;
			if (slot == 0)
				return topLeft;
			if (slot < width)
				return topLeft + BWAPI::Position(slotSize*slot, 0);
			if (slot < mid)
				return bottomRight - BWAPI::Position(0, slotSize*(mid-slot));
			if (slot == mid)
				return bottomRight;
			if ((slot > mid) && (slot <= units.size()-width))
				return bottomRight + BWAPI::Position(slotSize*(mid-slot), 0);
			return topLeft + BWAPI::Position(0, slotSize*(units.size() - slot));
		}
	case ZFBlock:
		{
			int width = ceil(sqrt((double)units.size()));
			int height = ceil((double)units.size()/width);
			BWAPI::Position offset((width-1)*slotSize/2, (width-1)*slotSize/2);
			int x = slot%width;
			int y = floor((double)slot/width);
			return getCenter() - offset + BWAPI::Position(slotSize*x, slotSize*y);
		}
		//case ZFHourGlassV: //Test
		//      {
		//              if (units.size() == 0)
		//                      return center;
		//              int circum = slotSize*(units.size()+2);
		//              int radius = 2 * ((radius = circum/2/PI) > slotSize ? radius : slotSize);
		//              double angle = 360.0*(slot)/units.size();
		//              double s = sin(angle * PI/180.0) / (abs(tan(angle * PI/180.0)) + 1);
		//              double c = cos(angle * PI/180.0) / (abs(tan(angle * PI/180.0)) + 1);
		//              return center + BWAPI::Position( radius*s, radius*c );
		//      }
		//case ZFHourGlassH: //Test
		//      {
		//              if (units.size() == 0)
		//                      return center;
		//              int circum = slotSize*(units.size()+1);
		//              int radius = 2 * ((radius = circum/2/PI) > slotSize ? radius : slotSize);
		//              double angle = 360.0*(slot)/units.size();
		//              double s = sin(angle * PI/180.0) / (abs(tan(angle * PI/180.0)) + 1);
		//              double c = cos(angle * PI/180.0) / (abs(tan(angle * PI/180.0)) + 1);
		//              return center + BWAPI::Position( radius*c, radius*s );
		//      }
	case ZFNone:
		return getCenter();
	}
	return getCenter();
}


std::set<CFormation*> CFormation::getFormations()
{
	std::set<CFormation*> local;
	for each (CFormation* formation in formations)
	{
		if (formation->units.size() > 0)
			local.insert(formation);
	}
	return local;
}

CFormation* CFormation::getEmptyFormation(BWAPI::Position center, EFormations formation)
{
	for (std::set<CFormation*>::iterator i = formations.begin(); i != formations.end(); ++i)
	{
		if (!(*i)->reserved && (*i)->units.size() == 0)
		{
			(*i)->setCenter(center);
			(*i)->setFormation(formation);
			return (*i);
		}
	}
	return new CFormation(center, formation);
}

void CalculateNearestSlots(CFormation::TUnitMap& units, std::map<int, BWAPI::Position> slots)
{
	typedef std::map<BWAPI::Unit*, std::pair<int, BWAPI::Position> > TMatch;

	CFormation::TUnitMap::iterator unitIter = units.begin();
	TMatch matches;
	std::map<int, BWAPI::Position>::const_iterator slotIter = slots.begin();

	for (; unitIter != units.end(); ++unitIter)
	{
		//Get closest unclaimed position
		std::map<int, BWAPI::Position>::const_iterator closest = slots.begin();
		if (closest != slots.end())
		{
			double dist = unitIter->first->getPosition().getDistance(closest->second);
			for (; slotIter != slots.end(); ++slotIter)
			{
				if (double next = unitIter->first->getPosition().getDistance(closest->second) < dist)
				{
					dist = next;
					closest = slotIter;
				}
			}
			unitIter->second = closest->first;
			matches.insert(std::make_pair(unitIter->first, (*closest)));
			slots.erase(closest);
		}
	}
	//seek trades
	for (TMatch::iterator iter = matches.begin(); iter != matches.end(); ++iter)
	{
		for (TMatch::iterator iter1 = matches.begin(); iter1 != matches.end(); ++iter1)
		{
			for (TMatch::iterator  iter2 = matches.begin(); iter2 != matches.end(); ++iter2)
			{
				double mineMine = iter1->first->getPosition().getDistance(iter1->second.second);
				double mineOther = iter1->first->getPosition().getDistance(iter2->second.second);
				double otherMine = iter2->first->getPosition().getDistance(iter1->second.second);

				if ((otherMine <= mineMine) && (mineOther <= mineMine)) //trade
				{
					std::pair<int, BWAPI::Position> otherSlot = iter2->second;
					iter2->second = iter1->second;
					iter1->second = otherSlot;
					if ((unitIter = units.find(iter1->first)) != units.end())
						unitIter->second = iter1->second.first;
					if ((unitIter = units.find(iter2->first)) != units.end())
						unitIter->second = iter2->second.first;
				}
			}
		}
	}
}

bool CFormation::onSendText(std::string text)
{
	if (text=="/fmt join")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
		{
			CFormation* formation = 0;
			CFormation* test = 0;
			std::set<CFormation*> merge;
			std::set<BWAPI::Unit*> add;
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
			{
				if (test = CFormation::getFormation(*i)) {
					if (!formation) {
						formation = test;
					} else {
						merge.insert(test);
					}
				} else {
					add.insert(*i);
				}
			}
			if (!formation) {
				formation = CFormation::getEmptyFormation(BWAPI::Broodwar->getMousePosition() + BWAPI::Broodwar->getScreenPosition());
			} else {
				formation->mergeFormations(merge);
			}
			for(std::set<BWAPI::Unit*>::const_iterator i = add.begin(); i != add.end(); ++i)
			{
				formation->joinFormation(*i);
			}
		}
		return false;
	} else if (text=="/fmt leave")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->leaveFormation(*i);
		return false;
	} else if (text=="/fmt split")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
		{
			CFormation* formation = 0;
			std::set<CFormation*> formations;
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
			{
				if (formation = CFormation::getFormation(*i))
						formations.insert(formation);
			}
			for(std::set<CFormation*>::const_iterator f = formations.begin(); f != formations.end(); ++f)
			{
				(*f)->splitFormation();
			}
		}
		return false;
	} else if (text=="/fmt disband")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->disbandFormation();
		return false;
	} else if ((text=="/fmt move") || (text=="/fmt mv"))
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setCenter(BWAPI::Broodwar->getMousePosition() + BWAPI::Broodwar->getScreenPosition());
		return false;
	} else if ((text=="/fmt waypoint") || (text=="/fmt way"))
	{
		std::vector<CFormation*> formations;
		if (BWAPI::Broodwar->getSelectedUnits().size())
		{
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formations.push_back(formation);
			for (int i = 0; i < formations.size(); ++i)
				formations[i]->addWayPoint(BWAPI::Broodwar->getMousePosition() + BWAPI::Broodwar->getScreenPosition());
		}
		return false;
	} else if (text=="/fmt none")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFNone);
		return false;
	} else if (text=="/fmt v")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFVLine);
		return false;
	} else if (text=="/fmt h")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFHLine);
		return false;
	} else if (text=="/fmt vv")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFDoubleVLine);
		return false;
	} else if (text=="/fmt vvd")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFDoubleVLineDense);
		return false;
	} else if (text=="/fmt hh")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFDoubleHLine);
		return false;
	} else if (text=="/fmt hhd")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFDoubleHLineDense);
		return false;
	} else if ((text=="/fmt /") || (text=="/fmt fore"))
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFForeslash);
		return false;
	} else if ((text=="/fmt \\") || (text=="/fmt back"))
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFBackslash);
		return false;
	} else if (text=="/fmt x")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFCross);
		return false;
	} else if (text=="/fmt +")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFPlus);
		return false;
	} else if (text=="/fmt box")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFBox);
		return false;
	} else if (text=="/fmt block")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFBlock);
		return false;
	} else if (text=="/fmt diamond")
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFDiamond);
		return false;
	} else if ((text=="/fmt circle") || (text=="/fmt o"))
	{
		if (BWAPI::Broodwar->getSelectedUnits().size())
			for(std::set<BWAPI::Unit*>::const_iterator i = BWAPI::Broodwar->getSelectedUnits().begin(); i != BWAPI::Broodwar->getSelectedUnits().end(); ++i)
				if (CFormation* formation = CFormation::getFormation(*i))
					formation->setFormation(ZFCircle);
		return false;
	}
	return true;
}
